home *** CD-ROM | disk | FTP | other *** search
- /*
- * Program to save/restore/verify the CMOS data of an AT BIOS.
- *
- * Copyright 1991-1994 Dave Dunfield
- * All rights reserved.
- *
- * Compile with: cc cmos -fop
- */
- #include <stdio.h>
-
- #define MAX_SIZE 128-0x10 /* Maximum potential size of CMOS ram */
-
- unsigned char buffer1[MAX_SIZE], buffer2[MAX_SIZE], verbose = -1;
-
- int size = 32, ignore[50]; icount = 0;
-
- char *help[] = {
- "\nUse: CMOS <command> <filename> [options]\n",
- "command: Save - Save CMOS data to a file",
- " Restore - Recover CMOS data from file",
- " Verify - Compare CMOS data to file\n",
- "options: -Q - QUIET, inhibit messages",
- " I=value - Ignore byte at this offset (Verify)",
- " S=value - Bytes of CMOS to SAVE (default 32)\n",
- "Copyright 1991 Dave Dunfield",
- "All rights reserved",
- 0 };
-
- /*
- * Main program
- */
- main(argc, argv)
- int argc;
- char *argv[];
- {
- int i;
- char *ptr;
- FILE *fp;
-
- if(argc < 3) {
- for(i = 0; help[i]; ++i) {
- fputs(help[i], stderr);
- putc('\n', stderr); }
- return; }
-
- for(i=3; i < argc; ++i) {
- ptr = argv[i];
- switch((*ptr++ << 8) | *ptr++) {
- case '-q' : /* Request QUIET mode */
- case '-Q' :
- verbose = 0;
- break;
- case 's=' : /* Specify size to save */
- case 'S=' :
- size = atoi(ptr);
- break;
- case 'i=' : /* Specify IGNORE bytes */
- case 'I=' :
- ignore[icount++] = atoi(ptr);
- break;
- default:
- fputs("Invalid option: ", stderr);
- fputs(argv[i], stderr);
- return; } }
-
- switch(*argv[1]) {
- case 's' : /* Save CMOS data to a file */
- case 'S' :
- read_cmos(buffer1, 0x1000+size);
- fp = fopen(argv[2], "wvqb");
- fwrite(buffer1, size, fp);
- fclose(fp);
- message("CMOS data saved");
- break;
- case 'r' : /* Restore CMOS data from a file */
- case 'R' :
- fp = fopen(argv[2], "rvqb");
- size = fread(buffer1, MAX_SIZE, fp);
- fclose(fp);
- write_cmos(buffer1, 0x1000+size);
- message("CMOS data restored");
- break;
- case 'v' : /* Verify CMOS data with file */
- case 'V' :
- fp = fopen(argv[2], "rvqb");
- size = fread(buffer2, MAX_SIZE, fp);
- fclose(fp);
- read_cmos(buffer1, 0x1000+size);
- for(i=0; i < icount; ++i)
- buffer1[ignore[i]] = buffer2[ignore[i]] = 0;
- for(i=0; i < size; ++i) {
- if(buffer1[i] != buffer2[i]) {
- message("CMOS verify FAILED!!!");
- exit(-1); } }
- message("CMOS Data verified");
- break;
- default: /* Invalid command */
- fputs("Unknown command: ", stderr);
- fputs(argv[1], stderr);
- return; }
- }
-
- /*
- * Issue message to used only if "verbose" enabled
- */
- message(string)
- char *string;
- {
- if(verbose)
- fputs(string, stdout);
- }
-
- /*
- * Read data from the CMOS ram
- */
- read_cmos(dest, addr_size) asm
- {
- MOV BX,6[BP] ; Get destination
- MOV CX,4[BP] ; Get start/size
- CLI ; Disallow interruptions
- rdloop: MOV AL,CH ; Get address
- OUT 70h,AL ; Write it
- INC CH ; Advance address
- IN AL,71h ; Read the data
- MOV [BX],AL ; Write it in dest
- INC BX ; Advance destination
- DEC CL ; Reduce count
- JNZ rdloop ; And continue
- STI ; Allow interruptions
- }
-
- /*
- * Write data to the CMOS ram
- */
- write_cmos(source, addr_size) asm
- {
- MOV BX,6[BP] ; Get destination
- MOV CX,4[BP] ; Get start/size
- CLI ; Disallow interruptions
- wrloop: MOV AL,CH ; Get address
- OUT 70h,AL ; Write it
- MOV AL,[BX] ; Get value to write
- OUT 71h,AL ; Write it
- INC CH ; Advance address
- INC BX ; Advance destination
- DEC CL ; Reduce count
- JNZ wrloop ; And continue
- STI ; Allow interruptions
- }
-